package x.ovo.wechat.bot.plugin;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.reflect.ClassUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.http.HttpUtil;
import org.dromara.hutool.json.JSONUtil;
import x.ovo.wechat.bot.core.event.Event;
import x.ovo.wechat.bot.core.event.EventListener;
import x.ovo.wechat.bot.core.plugin.Plugin;

import java.util.List;
import java.util.Map;

@Slf4j(topic = "HttpListener")
public class HttpListener extends EventListener<Event<Object>, Object> {
    public HttpListener(Plugin plugin) {
        super(plugin);
    }

    @Override
    public boolean support(@NonNull Event<Object> event, Object source) {
        return true;
    }

    @Override
    public boolean onEvent(@NonNull Event<Object> event, Object source) {
        try {
            String webhook = this.plugin.<String>getConfig().get("webhook");
            if (StrUtil.isBlank(webhook)) return false;

            // 判断事件类型是否在需要推送的列表内
            String className = ClassUtil.getClassName(event, true);
            List<String> list = this.plugin.<List<String>>getConfig().get("push_event");
            if (!CollUtil.contains(list, className)) return false;

            // 获取配置文件中的推送模板
            String template = this.plugin.<String>getConfig().get("body_template");
            // 去除第一个“{”，否则format有异常
            template = StrUtil.removePrefix(template, "{");
            String content = source instanceof String s ? s : JSONUtil.toJsonStr(source);
            content = StrUtil.replace(content, "\\\"", "\\\\\"");
            content = StrUtil.replace(content, "\"", "\\\"");
            String data = StrUtil.defaultIfBlank(StrUtil.formatByMap(template, Map.of("type", className, "content", content), false), content);
            // 将前缀“{”添加回去
            data = StrUtil.addPrefixIfNot(data, "{");
            HttpUtil.post(webhook, data);
            log.debug("push success, event: {}, data: {}", className, source);
            return true;
        } catch (Exception e) {
            log.warn("推送数据出现错误", e);
            return false;
        }
    }
}
